module ActiveBackground
  class Worker < ActiveBackground::Job

    def initialize(name, options={}, args={})
      super(name, options, args)
      @worker_threads = Hash.new
    end

    def process_job()
      # start working, this method is always run unless termination is called
      # in one of the methods registerd by before_work
      unless terminated?
        ACTIVE_BACKGROUND_LOGGER.debug('job ' + key + ' is processing')
        work()
      end
    end

    def work()
      ACTIVE_BACKGROUND_LOGGER.warn('You need to implement work or create tasks')
      ACTIVE_BACKGROUND_LOGGER.warn('trying to execute defined tasks')
      work_on :all
    end
    
    def work_on(*tasks)
      # if there are multiple tasks specified
      unless tasks[0] == :all
        for task in tasks
          # convert the taskname to method names. If a task
          # is called do_it the method should be task_do_it
          task = 'task_' + task.to_s
          # if there is alreaddy a thread lets skip performing
          # the task. This prevents multiple execution of tasks
          unless @worker_threads[task]
            @worker_threads[task] = Thread.new do
              # perform the task in its own thread
              self.send(task.to_sym)
            end
          end
        end
      else # work_on :all is called
        # we only process the public methods available to the class
        for method in self.public_methods
          # check if the method begins with task_
          if method.match('task_')
            # if there is already a thread lets skip performing
            # the task. This prevents multiple execution of tasks
            unless @worker_threads[method]
              @worker_threads[method] = Thread.new do
                # perform the task in its own thread
                self.send(method.to_sym)
              end
            end
          end
        end
      end
      # wait till all tasks are finished
      @worker_threads.each {|task, thread| thread.join}
      # reset to defaults if all tasks are finished
      @worker_threads = Hash.new
    end
  end
end